package com.itheima.stock.service.impl;

import com.alibaba.excel.EasyExcel;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.stock.mapper.StockBlockRtInfoMapper;
import com.itheima.stock.mapper.StockMarketIndexInfoMapper;
import com.itheima.stock.mapper.StockRtInfoMapper;
import com.itheima.stock.pojo.domain.*;
import com.itheima.stock.pojo.vo.StockInfoConfig;
import com.itheima.stock.service.StockService;
import com.itheima.stock.utils.DateTimeUtil;
import com.itheima.stock.vo.resp.PageResult;
import com.itheima.stock.vo.resp.R;
import com.itheima.stock.vo.resp.ResponseCode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;

@ApiModel
@Service
@Slf4j
public class StockServiceImpl implements StockService {
    @ApiModelProperty(hidden = true)
    @Autowired
    private StockInfoConfig stockInfoConfig;
    @ApiModelProperty(hidden = true)
    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;
    @ApiModelProperty(hidden = true)
    @Autowired
    private StockBlockRtInfoMapper stockBlockRtInfoMapper;

    //注入缓存
    @Autowired
    private Cache<String,Object> cache;

    //涨幅榜
    @ApiModelProperty("涨幅榜")
    @Autowired
    private StockRtInfoMapper stockRtInfoMapper;

    @Override
    public R<List<InnerMarkDomain>> getInnerMarketInfo() {

        //缓存加载
        R<List<InnerMarkDomain>> result= (R<List<InnerMarkDomain>>) cache.get("innerMarketKey", key->{

            //1.获取当前时间，精确到分钟
//        DateTime curDate = DateTimeUtil.getLastDate4Stock(DateTime.now()).toDateTime();
            //(1).暂时无采集，使用假数据时间
            Date curDate = DateTime.parse("2021-12-28 09:31:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")).toDate();
            //2.获取大盘编码
            List<String> mCodes = stockInfoConfig.getInner();

            //3.调用mapper查询；
            List<InnerMarkDomain> data = stockMarketIndexInfoMapper.getMarkInfo(curDate, mCodes);
            return R.ok(data);
        });

return result;
    }

    //国内板块指数功能实现
    @Override
    public R<List<StockBlockDomain>> getSectorAll() {
        Date lastDate = DateTimeUtil.getLastDate4Stock(DateTime.now()).toDate();
        //假数据后续删除
        lastDate = DateTime.parse("2021-12-27 14:30:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")).toDate();

        List<StockBlockDomain> infos = stockBlockRtInfoMapper.sectorAllLimit(lastDate);
        //如果为空，错误
        if (CollectionUtils.isEmpty(infos)) {
            return R.error(ResponseCode.NO_RESPONSE_DATA.getMessage());
        }
        return R.ok(infos);
    }

    /**
     * 分页查询最新股票交易
     *
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public R<PageResult<StockUpdownDomain>> getStockInfoByPage(Integer page, Integer pageSize) {
        //1.获取指定时间，精确到分钟
        DateTime curDate = DateTimeUtil.getLastDate4Stock(DateTime.now()).toDateTime();
        Date curdateTime = curDate.toDate();
        //(1).暂时无采集，使用假数据时间
         curdateTime = DateTime.parse("2021-12-30 09:42:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")).toDate();
        PageHelper.startPage(page, pageSize);
        List<StockUpdownDomain> pageDta = stockRtInfoMapper.getStockInfoByTime(curdateTime);
        PageInfo<StockUpdownDomain> pageInfo = new PageInfo<>(pageDta);
        PageResult<StockUpdownDomain> pageResult = new PageResult<>(pageInfo);

        return R.ok(pageResult);
    }

    // 涨幅榜数据采集
    @Override
    public R<List<StockUpdownDomain>> getUpDownStockInfo() {
        //1.获取指定时间，精确到分钟
//        DateTime curDate = DateTimeUtil.getLastDate4Stock(DateTime.now()).toDateTime();
        //(1).暂时无采集，使用假数据时间
        Date curDate = DateTime.parse("2022-07-13 14:49:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")).toDate();
        List<StockUpdownDomain> stockInfoByTime = stockRtInfoMapper.getStockInfoByTimeNopage(curDate);
        if (stockInfoByTime == null) {
            return R.error(ResponseCode.NO_RESPONSE_DATA.getMessage());
        }
        return R.ok(stockInfoByTime);
    }

    //涨停
    @Override
    public R<Map<String, List>> getStockUpDown() {

        //1.获取当天截止时间，精确到分钟
        DateTime curDateTime = DateTimeUtil.getLastDate4Stock(DateTime.now());
        //(1).暂时无采集，使用假数据时间
        curDateTime = DateTime.parse("2022-01-06 14:25:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));

        Date endDate = curDateTime.toDate();
        //2.当天开盘时间
        Date startDate = DateTimeUtil.getOpenDate(curDateTime).toDate();
        //涨停
        List<Map> upList = stockRtInfoMapper.getStockUpDownCount(startDate, endDate, 1);
        //跌停
        List<Map> downList = stockRtInfoMapper.getStockUpDownCount(startDate, endDate, 0);
        HashMap<String, List> info = new HashMap<>();
        info.put("upList", upList);
        info.put("downList", downList);
        return R.ok(info);
    }

    /**
     * //股票展示分页--导出--数据
     *
     * @param page
     * @param pageSize
     * @param resp
     */

    @Override
    public void exportStockUpDownInfo(Integer page, Integer pageSize, HttpServletResponse resp) {
        //1.获取分页数据
        R<PageResult<StockUpdownDomain>> r = this.getStockInfoByPage(page, pageSize);
        List<StockUpdownDomain> rows = r.getData().getRows();

        resp.setContentType("application/vnd.ms-excel");
        resp.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        try {
            String fileName = URLEncoder.encode("股票信息股", "UTF-8");
            resp.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(resp.getOutputStream(), StockUpdownDomain.class).sheet("股票涨幅信息").doWrite(rows);
        } catch (IOException e) {
            log.error("当前页码:{},每页大小:{},当前时间:{},异常信息:{}",
                    page, pageSize, DateTime.now().toString("yyyy-MM-dd HH:mm:ss"), e.getMessage());

            //通知前端异常
            resp.setContentType("application/json");
            resp.setCharacterEncoding("utf-8");
            R<Object> error = R.error(ResponseCode.ERROR);
            try {
                String jsonDdata = new ObjectMapper().writeValueAsString(error);
                resp.getWriter().write(jsonDdata);
            } catch (IOException ex) {
                log.error("exportStockUpDownInfo:响应错误信息失败,时间:{}", DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
            }
        }
    }

    /**
     * 统计T日和T-1每分钟交易额
     *
     * @return
     */
    @Override
    public R<Map<String, List>> getComparedStockTradeAmt() {
        //截止时间
        DateTime TendDatetime = DateTimeUtil.getLastDate4Stock(DateTime.now());
        //假数据后续删除
                 TendDatetime = DateTime.parse("2022-01-03 14:40:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));
           //T日结束
        Date tedate = TendDatetime.toDate();
        //T日开盘时间,改成9.30
        Date tsdate = DateTimeUtil.getOpenDate(TendDatetime).toDate();


        //获取T-1，结束
        DateTime preTendDateTime = DateTimeUtil.getPreviousTradingDay(TendDatetime);
                 preTendDateTime = DateTime.parse("2022-01-02 14:40:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));
        //假数据后续删除
        Date preTendDate = preTendDateTime.toDate();
        //开盘T-1日
        Date preTstartDate = DateTimeUtil.getOpenDate(preTendDateTime).toDate();

        //统计T日
        List<Map> tDate = stockMarketIndexInfoMapper.getSumAmtInfo(tsdate, tedate, stockInfoConfig.getInner());
        //统计T-1日
        List<Map> pretDate = stockMarketIndexInfoMapper.getSumAmtInfo(preTstartDate, preTendDate, stockInfoConfig.getInner());

        HashMap<String, List> info = new HashMap<>();
        info.put("amtList", tDate);
        info.put("yesAmtList", pretDate);


        return R.ok(info);
    }


    /**
     * 统计最新时间股票各个涨幅区间的个数
     *
     * @return
     */
    @Override
    public R<Map> getIncreaseRangeInfo() {
        //获取最新时间
        DateTime curDatetime = DateTimeUtil.getLastDate4Stock(DateTime.now());
        //假数据后续删除
        curDatetime = DateTime.parse("2022-01-06 09:55:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));
        Date curdate = curDatetime.toDate();

        List<Map> infos = stockRtInfoMapper.getIncreaseRangeInfoByDate(curdate);
        List<String> upDownRange = stockInfoConfig.getUpDownRange();//获取区间标题--值
        List<Map> allInfos = new ArrayList<>();


        for (String title : upDownRange) {//遍历标题--值
            Map tmp = null;
            for (Map info : infos) {
                if (info.containsValue(title)) {
                    tmp = info;
                    break;
                }
            }
            if (tmp == null) {
                tmp = new HashMap();
                tmp.put("count", 0);
                tmp.put("title", title);
            }
            allInfos.add(tmp);

        }

        HashMap<String, Object> data = new HashMap<>();
        data.put("time", curDatetime.toString("yyyy-MM-dd HH:mm:ss"));
//        data.put("infos",infos);
        data.put("infos", allInfos);
        return R.ok(data);
    }


    /**
     * T日分时数据线
     *
     * @param
     * @return
     */
    @Override
    public R<List<Stock4MinuteDomain>> getScreenTimeSharing(String stockCode) {
        //获取最新时间
        DateTime endDatetime = DateTimeUtil.getLastDate4Stock(DateTime.now());
        //假数据后续删除
        endDatetime = DateTime.parse("2021-12-30 14:30:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));
        Date endDate = endDatetime.toDate();

        //开盘时间
        Date openDate = DateTimeUtil.getOpenDate(endDatetime).toDate();
        List<Stock4MinuteDomain> data = stockRtInfoMapper.getStock4MinuteInfo(openDate, endDate, stockCode);
        return R.ok(data);
    }


    /**
     * 统计股票日k线
     *
     * @param stockCode
     * @return
     */
    @Override
    public R<List<Stock4EvrDayDomain>> getScreenDKline(String stockCode) {
        DateTime endDatetime = DateTimeUtil.getLastDate4Stock(DateTime.now());
        //假数据
                endDatetime = DateTime.parse("2022-07-15 15:47:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));

        //截止时间
        Date endDate = endDatetime.toDate();

        //开始时间
        DateTime startDateTime = endDatetime.minusMonths(3);
                 startDateTime=DateTime.parse("2022-07-01 09:47:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));

        Date startDate = startDateTime.toDate();
//       List<Stock4EvrDayDomain> dKLine= stockRtInfoMapper.getStock4DKline(startDate,endDate,stockCode);
      //  拆分成功
       List<String> times= stockRtInfoMapper.getTimeByRT(startDate,endDate,stockCode);

        List<Stock4EvrDayDomain> dKLine=  stockRtInfoMapper.get4DKLine(times,stockCode);

        return R.ok(dKLine);
    }
}

